/*
 * 
*/
dynamic class SlipPic{
	public static var MS_WIN:String="onWin";

	private var $pics:Array;
	private var $w:Number;
	private var $h:Number;
	
	private var $moveSpeed:Number=3;
	private var $mouseCheck:Object;
	private var $stepSum:Number;
	
	public function SlipPic(w:Number,h:Number,pics:Array){
		this.$pics=new Array();
		this.$w=w;
		this.$h=h;
		initvars();
		initpics(pics);
		initMsg();
	}
	public function Restart(){
		initvars();
		randomPic();
	}
	private function initMsg(){
		AsBroadcaster.initialize(this);
	}
	private function initvars(){
		this.$stepSum=0;
		this.stopMouseAction();
		this.$mouseCheck=new Object();
		this.$mouseCheck.root=this;
		this.$mouseCheck.tag1=null;
		this.$mouseCheck.tag2=null;
		this.$mouseCheck.onMouseDown=this.OnMouseDownFun;
		Mouse.addListener(this.$mouseCheck);
	}
	private function stopMouseAction(){
		Mouse.removeListener(this.$mouseCheck);
	}
	private function OnMouseDownFun(){
		this.root.$stepSum++;
		if(this.root.$pics[0]==null){
			this.root.stopMouseAction();
			return;
		}
		var hitmc=this.root.getClickMc();
		//Debug.traceAllObj(hitmc.index);
		if(this.tag1==undefined && this.tag2==null){
			this.tag1=hitmc;
		}else if(this.tag1!=undefined && this.tag2==null){
			this.tag2=hitmc;
			var xl=this.tag1.index.x-this.tag2.index.x;
			var yl=this.tag1.index.y-this.tag2.index.y;
			
			if((Math.abs(xl)==1 && Math.abs(yl)==0)||(Math.abs(xl)==0 && Math.abs(yl)==1)){
				this.root.swich(this.tag1,this.tag2);
				this.tag1=null;
				this.tag2=null;
				if(this.root.checkRight()){
					trace(true);
					this.root.broadcastMessage(SlipPic.MS_WIN);
					this.root.stopMouseAction();
				}else{
					trace(false);
				}
			}else{
				this.tag1=this.tag2;
				this.tag2=null;
			}
		}
	}
	private function getClickMc():MovieClip{
		for(var i=0;i<this.$pics.length;i++){
			if(this.$pics[i].hitTest(_root._xmouse,_root._ymouse,true)){
				return this.$pics[i];
			}
		}
		return null;
	}
	private function initpics(picmcs:Array){
		
		for(var y=0;y<this.$h;y++){
			for(var x=0;x<this.$w;x++){
				var mc:MovieClip=MovieClip(picmcs.shift());
				mc.root=this;
				mc.id={y:y,x:x};
				mc.index={y:y,x:x};
				mc.mb={x:mc._x,y:mc._y};
				
				this.$pics.push(mc);
			}
		}
		trace(checkRight());
		randomPic();
		trace(checkRight());
	}
	
	private function checkRight():Boolean{
		for(var i=0;i<this.$pics.length;i++){
			if(!equ(this.$pics[i].id,this.$pics[i].index)){
				return false;
			}
		}
		return true;
	}
	private function randomPic(){
		for(var i=0;i<this.$pics.length;i++){
			var rindex:Number=int(Math.random()*this.$pics.length-i)+i;
			this.swich(this.$pics[rindex],this.$pics[i]);
		}
	}
	private function swich(mc1:MovieClip,mc2:MovieClip){
		var temp={};
			temp.y=mc1.index.y;
			temp.x=mc1.index.x;
			mc1.index.y=mc2.index.y;
			mc1.index.x=mc2.index.x;
			
			mc2.index.y=temp.y;
			mc2.index.x=temp.x;
			
			
			var x1=mc2.mb.x;
			var y1=mc2.mb.y;
			var x2=mc1.mb.x;
			var y2=mc1.mb.y;
			
			mc1.mb={x:x1,y:y1}
			mc2.mb={x:x2,y:y2}
			
			mc1.onEnterFrame=this.MovieMc;
			mc2.onEnterFrame=this.MovieMc;
	}
	private function MovieMc(){
		var xl=this.mb.x-this._x;
		var yl=this.mb.y-this._y;
		if(Math.abs(xl)>0.2 || Math.abs(yl)>0.2){
			this._x+=xl/this.root.$moveSpeed;
			this._y+=yl/this.root.$moveSpeed;
		}else{
			this._x=this.mb.x;
			this._y=this.mb.y;
			delete this.onEnterFrame;
		}
	}
	private function equ(obj1,obj2):Boolean{
		var names:String=",";
		for(var i in obj1){
			trace("check:"+i+": "+obj2[i]+" ?= "+obj1[i]+" ("+(obj2[i]==obj1[i])+")");
			if(obj2[i]!=obj1[i]){
				return false;
			}
			names+=i+",";
		}
		
		for(var i in obj2){
			if(names.indexOf(i)<0){
				return false;
			}
		}
		return true;
	}
}